package com.ruoyi.common.utils.security;

import org.apache.shiro.codec.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import java.io.IOException;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


public class RSAUtil {
	private static final Logger logger = LoggerFactory.getLogger(RSAUtil.class);

	public static String RSA_PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCk5WQOTeV02xdkih4Vtd8QjgtCo32dByleuqzyxCvAZZJuLEyPFVggku82DyvMIebICnvmLi2uJ";

	/**
	 * 生成密钥对
	 * @return
	 * @throws Exception
	 */
	public static KeyPair getKeyPair() throws Exception {
		KeyPairGenerator keyPairGenerator  = KeyPairGenerator.getInstance("RSA");
		keyPairGenerator.initialize(2048);
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		return keyPair;
	}

	/**
	 * 获取公钥（BASE64编码）
	 * @throws IOException
	 */
	public static String getPublicKey(KeyPair keyPair) throws IOException {
		PublicKey publicKey = keyPair.getPublic();
		byte[] bytes = publicKey.getEncoded();
		return new String(Base64.encode(bytes)).replaceAll("[\\s*\t\n\r]","");
	}


	/**
	 * 获取私钥（BASE64编码）
	 * @return
	 * @throws IOException
	 */
	public static  String getPrivateKey(KeyPair keyPair) throws IOException {
		PrivateKey privateKey = keyPair.getPrivate();
		byte[] bytes  =privateKey.getEncoded();
		return new String(Base64.encode(bytes)).replaceAll("[\\s*\t\n\r]","");
	}


	/**
	 * 将BASE64编码后的公钥转成PublicKey
	 * @param publicString
	 * @return
	 * @throws Exception
	 */
	public static PublicKey String2PublicKey(String publicString) throws Exception {
		byte[] keyBytes = Base64.decode(publicString);
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		return publicKey;
	}

	/**
	 * 将BASE64编码后的私钥转成PrivateKey
	 * @param privateString
	 * @return
	 * @throws IOException
	 */
	public static PrivateKey String2PrivateKey(String privateString) throws Exception {
		byte[] keyBytes = Base64.decode(privateString);
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		return privateKey;
	}


	/**
	 * 公钥加密
	 * @param content
	 * @param publicKey
	 * @return
	 * @throws Exception
	 */
	public static byte[] publicEncrypt(byte[] content,PublicKey publicKey) throws Exception{
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		byte[] bytes = cipher.doFinal(content);
		return bytes;
	}


	/**
	 * 私钥解密
	 * @param content
	 * @param privateKey
	 * @return
	 * @throws Exception
	 */
	public static byte[] privateDecrypt(byte[] content,PrivateKey privateKey) throws Exception {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		byte[] bytes = cipher.doFinal(content);
		return bytes;
	}

	/**
	 * 获取原始密码
	 * @param inputPwd RSA加密之后的密码
	 * @return
	 * @throws Exception
	 */
	public static String originPwd(String inputPwd){
		try {
            String privateKeyString  = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTAnPjiNoYIFaSOO3l45t9azquBz/E0KiCVrjkDoMkNA8ayZjCIAQqHR5GrCnRJk13kyLuEwbWQFtDcGrGYY5fV7brNFkRNw8e5zcy+9vFRMnZjBqd4IBGrzOHAYwlxXzyprFZ+JrmpCVH/COl9zM9B7pvpmunOhircwFmd68hOl+XVv295DMS2R35M9/a+YOVYEtRLKBk2XQLKpm8Ank5CwcqyqSNmMDnGXwcCTvmOXK+2xIy/dGuJs9AgzFolIyBTWpJkdpurzJOImhnD5pgGb9fhWgekfE2EPuawuA41GUPYsF/9QGnjf1LhcoaSZV5kZCvVSna87wGpYVCt/qDAgMBAAECggEAOgC/mHlC8kTZZ0Js6rehQ12ZeMMXXWO6HnH2SwJOPEJvMH7gFeS1IFp2uxiSOiLcQpVYkbb7NyPjsmsRfszMVRsIdikinp/S8Ty/qK0g4V4iWkGwA1v2BvgcIu1i9/MMgKsfr0quUd4nPV1q8zE7jXg1YIGPsB1BMMfhR6h4pJomRHkC9WStF1F7LSgZvUywcShwhAptlhfuaa0a279Hv5deUfulx9vK5J+lvfTrP51gWHVE4EE1dqxs4qjbU0vX62HRLpmdkP/8dqioCIlTmXkS+fMwxT290n5i7yiVXHEYyg8M3opYb0vj1uF215qOf9n5KgHO7MiZqf/BYLIuEQKBgQD0EPsvsw7jtcMjrkC/XoV/dUijrhfHiXtf711GEs5OHL2pBGx9y/y1atUHCLaa25xtDr6CzsyRonFSx5h9ZOX1fg+gL0x5JxFsmAdqgSFD/Dfxm6LmatdzVxmbnlO9mzYm+NsMDjefgODlRjjw1Nw7JVtvtfoyx0Hml50mfdjKOwKBgQDdU7HUD8/jk/VNDyYECAHahQCCwRg0v35beoytGmp5Msurv22hPhk6Rje4OaOGneUj9VmaaUOoGIc82eunzjS39pyxTLE8AupcE5C+TdFnN9WiH+/wfoghEub7+tlzLIolUS26yxAsZfbt1VX5yJj2ibFN3WsJva+cTKqBWcZEWQKBgEB3x9G2q2Usmsnu+j1SW1LqiPBrSO60+vjBQlMDHql1YAeoGnw0CKFnAbQk8g7/mVcZQOtOcqy5StPB0x60KyXoUXpPZBTQZALaOYNBbqcFlUVlheb1K8nUpPf9H0ODHw+2Ri3uB3VDVqRZIytCHpYk7P0aBWeqSFb/j0wei8gHAoGAHOQvA3qo7ZFD5TJECSSucUMJZQgly8Tvjqt5r6MSIQ4TbjEH85NyoZvG7EKB6TG1VrNRZgm1rjy9cqET1Qzi7ty/aZmUTTwoMarQKzdnTW0JcyduH9u0k3SvOFdviUxYIDTvnkGhs9n/mN5PYdLgvNYOkhaEQXpEcUfEvivk6MkCgYEAmYlNkbFRuTzgOetyewXc0af9s6fXWybQzLn+SWjg9ZXjVRGa/4TSeRYYlKNl5sJvqO2rMrugYbL5sPWBORoIxZ+Gak8wp7LqjoDOC5O3wEOkD97A08WftNXPgkk1UW5aMdZ/2Jxk/LXYH4AFnerX02TLH4qGgPv9QXOrghf18iE=";
			//解密
            PrivateKey privateKey = String2PrivateKey(privateKeyString);

            byte[] privateDecrypt = privateDecrypt(Base64.decode(inputPwd), privateKey);
            return new String(privateDecrypt);

		} catch (Exception e) {
			logger.warn("RSA解密: 获取原始密码异常!",e);
			return e.getMessage();
		}
	}

	/**
	 * 密码加密
	 * @param inputPwd 原始密码
	 * @param salt     盐值
	 * @return
	 * @throws Exception
	 */
	public static String EncryptPwd(String inputPwd,String salt) throws Exception {
		try {
			String testPassword = inputPwd+salt;
			//加密
			String publicKeyString ="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0wJz44jaGCBWkjjt5eObfWs6rgc/xNCogla45A6DJDQPGsmYwiAEKh0eRqwp0SZNd5Mi7hMG1kBbQ3BqxmGOX1e26zRZETcPHuc3MvvbxUTJ2YwaneCARq8zhwGMJcV88qaxWfia5qQlR/wjpfczPQe6b6ZrpzoYq3MBZnevITpfl1b9veQzEtkd+TPf2vmDlWBLUSygZNl0CyqZvAJ5OQsHKsqkjZjA5xl8HAk75jlyvtsSMv3RribPQIMxaJSMgU1qSZHabq8yTiJoZw+aYBm/X4VoHpHxNhD7msLgONRlD2LBf/UBp439S4XKGkmVeZGQr1Up2vO8BqWFQrf6gwIDAQAB";
			PublicKey publicKey = String2PublicKey(publicKeyString);

			byte[] publicEncrypt = publicEncrypt(testPassword.getBytes(), publicKey);
			String pass = new String(Base64.encode(publicEncrypt));
			return pass;
		} catch (Exception e) {
			throw  e;
		}
	}



}
